package newtank;

import lombok.Getter;
import lombok.Setter;
import newtank.data.AbstractDataPackage;
import newtank.data.EnvironmentInitSignal;
import newtank.network.server.ClientNetwork;
import newtank.utils.ExecutorsUtils;
import newtank.view.HandlerKeyListener;
import newtank.view.PaintView;
import newtank.view.TankDrawingCloth;
import newtank.view.context.TankViewContext;
import newtank.view.context.WindowViewContext;
import newtank.view.operate.AbstractOperatorHandler;
import newtank.view.operate.RepaintHandler;
import newtank.view.operate.ShootHandler;
import newtank.view.operate.TankMoveHandler;
import sun.security.provider.MD5;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 坦克大战客户端
 * @author lijiahao
 * @since 2022/1/27
 */
public class TankClientFrame extends JFrame {

    private static final long serialVersionUID = -8561793821999454293L;

    /**
     * 客户端动态序列号
     */
    @Getter
    private String dynamicSelfUnique;

    /**
     * 客户端参数缓存
     */
    private final WindowViewContext clientContext = new WindowViewContext();

    /**
     * 数据核心处理器
     */
    @Getter
    private final List<TankViewContext> tankViewContexts = new ArrayList<>();

    private final List<AbstractOperatorHandler> operatorHandlers = new ArrayList<>();

    @Setter
    @Getter
    private TankViewContext selfTankContext;

    /**
     * 渲染画布
     */
    @Getter
    private final TankDrawingCloth drawingCloth;

    /**
     * 客户端网络层
     */
    private final ClientNetwork netWorkClient;

    /**
     * 运行状态
     */
    @Getter
    @Setter
    private Boolean runStatus;

    private static TankClientFrame tankClientFrame;


    public static TankClientFrame getInstance() {
        if(tankClientFrame == null) {
            tankClientFrame = new TankClientFrame();
            tankClientFrame.initHandler();
        }
        return tankClientFrame;
    }

    private TankClientFrame() {
        super();
        staticLoadProperty(clientContext);
        netWorkClient = ClientNetwork.builder(clientContext.getServerIp(), clientContext.getServerPort());
        drawingCloth = new TankDrawingCloth(clientContext.getClothColor());
        this.runStatus = Boolean.TRUE;
    }

    public void initHandler() {
        TankMoveHandler tankMoveHandler = new TankMoveHandler();
        tankMoveHandler.setTankClientFrame(this);
        tankMoveHandler.setTankDrawingCloth(drawingCloth);
        operatorHandlers.add(tankMoveHandler);
        ShootHandler shootHandler = new ShootHandler();
        shootHandler.setTankClientFrame(this);
        shootHandler.setTankDrawingCloth(drawingCloth);
        operatorHandlers.add(shootHandler);
        RepaintHandler repaintHandler = new RepaintHandler(drawingCloth);
        HandlerKeyListener listener = new HandlerKeyListener(operatorHandlers);
        listener.setTankDrawingCloth(drawingCloth);
        addKeyListener(listener);
        ExecutorsUtils.executeRepaint(repaintHandler);
    }

    public void setDynamicRegistryId(String selfUnique) {
        this.dynamicSelfUnique = selfUnique;
    }

    public void initConn() {
        try {
            //连接主服务器
            System.out.println("新建数据库连接");
            netWorkClient.start();
            //发送环境初始化数据包
            netWorkClient.sendMessage(new EnvironmentInitSignal());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void sendMessage(AbstractDataPackage abstractDataPackage) {
        netWorkClient.sendMessage(abstractDataPackage);
    }

    /**
     * 静态属性加载
     * @param windowViewContext
     */
    private void staticLoadProperty(WindowViewContext windowViewContext) {
        windowViewContext.setServerIp("127.0.0.1");
        windowViewContext.setServerPort(8000);
        windowViewContext.setTitle("坦克大战 1.0");
        windowViewContext.setWidth(900);
        windowViewContext.setHeight(750);
        windowViewContext.setMdVersion(new MD5().toString());
        windowViewContext.setClothColor(Color.BLUE);
    }

    public void initFrame() {
        // 设置 窗口标题 和 窗口大小
        drawingCloth.resetPaintView(getPaintViews());

        setTitle(clientContext.getTitle() + this.getDynamicSelfUnique());
        setSize(clientContext.getWidth(), clientContext.getHeight());
        // 设置窗口关闭按钮的默认操作(点击关闭时退出进程)
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        // 把窗口位置设置到屏幕的中心
        setLocationRelativeTo(null);
        setContentPane(drawingCloth);
        setVisible(true);
    }

    public List<PaintView> getPaintViews() {
        List<PaintView> paintViewList = new ArrayList<>(TankViewContext.createTankView(tankViewContexts, clientContext.getWidth(), clientContext.getHeight()));
        if(paintViewList.isEmpty()) {
            paintViewList.add(TankViewContext.createView(clientContext.getWidth(), clientContext.getHeight()));
        }
        return paintViewList;
    }

    public void addPaintViews(List<TankViewContext> tankViewContexts) {
        this.tankViewContexts.addAll(tankViewContexts);
        List<PaintView> paintViewList = new ArrayList<>(TankViewContext.createTankView(tankViewContexts,
                clientContext.getWidth(),
                clientContext.getHeight()));
        drawingCloth.addPaintView(paintViewList);
    }

    public PaintView getView(String unique) {
        return drawingCloth.getView(unique);
    }

    public static void main(String[] args) {
        TankClientFrame mapClothFrame = TankClientFrame.getInstance();
        //网络连接
        mapClothFrame.initConn();
    }
}
